home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / tcp / amitcp / amitcp-src-22.lha / AmiTCP-2.2 / src / appl / finger / util.c < prev   
Encoding:
C/C++ Source or Header  |  1993-10-14  |  8.8 KB  |  366 lines

  1. RCS_ID_C = "$Id: util.c,v 6.2 93/10/15 03:01:49 ppessi Exp $";
  2.  
  3. /*
  4.  * util.c - Utility functions for finger
  5.  *
  6.  * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-group@hut.fi>
  7.  *                  Helsinki University of Technology, Finland.
  8.  *
  9.  * This program is derived from original work distributed in BSD Net 2.
  10.  *
  11.  * Created      : Fri Oct 15 01:29:07 1993 ppessi
  12.  * Last modified: Fri Oct 15 01:39:39 1993 ppessi
  13.  *
  14.  * $Log:    util.c,v $
  15.  * Revision 6.2  93/10/15  03:01:49  ppessi
  16.  * Polished AmiTCP support
  17.  * 
  18.  */
  19.  
  20. /*
  21.  * Copyright (c) 1989 The Regents of the University of California.
  22.  * All rights reserved.
  23.  *
  24.  * This code is derived from software contributed to Berkeley by
  25.  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
  26.  *
  27.  * Redistribution and use in source and binary forms, with or without
  28.  * modification, are permitted provided that the following conditions
  29.  * are met:
  30.  * 1. Redistributions of source code must retain the above copyright
  31.  *    notice, this list of conditions and the following disclaimer.
  32.  * 2. Redistributions in binary form must reproduce the above copyright
  33.  *    notice, this list of conditions and the following disclaimer in the
  34.  *    documentation and/or other materials provided with the distribution.
  35.  * 3. All advertising materials mentioning features or use of this software
  36.  *    must display the following acknowledgement:
  37.  *    This product includes software developed by the University of
  38.  *    California, Berkeley and its contributors.
  39.  * 4. Neither the name of the University nor the names of its contributors
  40.  *    may be used to endorse or promote products derived from this software
  41.  *    without specific prior written permission.
  42.  *
  43.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  44.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  45.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  46.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  47.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  48.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  49.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  50.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  51.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  52.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  53.  * SUCH DAMAGE.
  54.  */
  55.  
  56. static char sccsid[] = "@(#)util.c    5.14 (Berkeley) 1/17/91";
  57.  
  58. #include <sys/param.h>
  59. #include <sys/stat.h>
  60. #if AMIGA
  61. #include <fcntl.h>
  62. #else
  63. #include <sys/file.h>
  64. #endif
  65. #include <stdlib.h>
  66. #include <stdio.h>
  67. #include <ctype.h>
  68. #include <string.h>
  69. #if !AMIGA
  70. #include <paths.h>
  71. #endif
  72. #include "finger.h"
  73.  
  74. char *strsep(register char **stringp, register const char *delim);
  75.  
  76. /* Local prototypes */
  77. int hash(register char *name);
  78.  
  79. #if !AMIGA
  80. find_idle_and_ttywrite(w)
  81.      register WHERE *w;
  82. {
  83.   extern time_t now;
  84.   extern int errno;
  85.   struct stat sb;
  86.   char *strerror();
  87.  
  88.   (void)sprintf(tbuf, "%s/%s", _PATH_DEV, w->tty);
  89.   if (stat(tbuf, &sb) < 0) {
  90.     (void)fprintf(stderr,
  91.           "finger: %s: %s\n", tbuf, strerror(errno));
  92.     return;
  93.   }
  94.   w->idletime = now < sb.st_atime ? 0 : now - sb.st_atime;
  95.  
  96. #define    TALKABLE    0220    /* tty is writable if 220 mode */
  97.   w->writable = ((sb.st_mode & TALKABLE) == TALKABLE);
  98. }
  99. #endif
  100.  
  101. void
  102. userinfo( register PERSON *pn, register struct passwd *pw)
  103. {
  104.   register char *p, *t;
  105.   char *bp, name[1024];
  106.  
  107.   pn->realname = pn->office = pn->officephone = pn->homephone = NULL;
  108.  
  109.   pn->uid = pw->pw_uid;
  110.   pn->name = strdup(pw->pw_name);
  111.   pn->dir = strdup(pw->pw_dir);
  112.   pn->shell = strdup(pw->pw_shell);
  113.  
  114.   /* why do we skip asterisks!?!? */
  115.   (void)strcpy(bp = tbuf, pw->pw_gecos);
  116.   if (*bp == '*')
  117.     ++bp;
  118.  
  119.   /* ampersands get replaced by the login name */
  120.   if (!(p = strsep(&bp, ",")))
  121.     return;
  122.   for (t = name; *t = *p; ++p)
  123.     if (*t == '&') {
  124.       (void)strcpy(t, pw->pw_name);
  125.       if (islower(*t))
  126.     *t = toupper(*t);
  127.       while (*++t);
  128.     }
  129.     else
  130.       ++t;
  131.   pn->realname = strdup(name);
  132.   pn->office = ((p = strsep(&bp, ",")) && *p) ?
  133.     strdup(p) : NULL;
  134.   pn->officephone = ((p = strsep(&bp, ",")) && *p) ?
  135.     strdup(p) : NULL;
  136.   pn->homephone = ((p = strsep(&bp, ",")) && *p) ?
  137.     strdup(p) : NULL;
  138. }
  139.  
  140. #if !AMIGA
  141. match(pw, user)
  142.      struct passwd *pw;
  143.      char *user;
  144. {
  145.   register char *p, *t;
  146.   char name[1024];
  147.  
  148.   /* why do we skip asterisks!?!? */
  149.   (void)strcpy(p = tbuf, pw->pw_gecos);
  150.   if (*p == '*')
  151.     ++p;
  152.  
  153.   /* ampersands get replaced by the login name */
  154.   if (!(p = strtok(p, ",")))
  155.     return(0);
  156.   for (t = name; *t = *p; ++p)
  157.     if (*t == '&') {
  158.       (void)strcpy(t, pw->pw_name);
  159.       while (*++t);
  160.     }
  161.     else
  162.       ++t;
  163.   for (t = name; p = strtok(t, "\t "); t = (char *)NULL)
  164.     if (!strcasecmp(p, user))
  165.       return(1);
  166.   return(0);
  167. }
  168.  
  169. enter_lastlog(pn)
  170.      register PERSON *pn;
  171. {
  172.   register WHERE *w;
  173.   static int opened, fd;
  174.   struct lastlog ll;
  175.   char doit = 0;
  176.   off_t lseek();
  177.  
  178.   /* some systems may not maintain lastlog, don't report errors. */
  179.   if (!opened) {
  180.     fd = open(_PATH_LASTLOG, O_RDONLY, 0);
  181.     opened = 1;
  182.   }
  183.   if (fd == -1 ||
  184.       lseek(fd, (long)pn->uid * sizeof(ll), L_SET) !=
  185.       (long)pn->uid * sizeof(ll) ||
  186.       read(fd, (char *)&ll, sizeof(ll)) != sizeof(ll)) {
  187.     /* as if never logged in */
  188.     ll.ll_line[0] = ll.ll_host[0] = NULL;
  189.     ll.ll_time = 0;
  190.   }
  191.   if ((w = pn->whead) == NULL)
  192.     doit = 1;
  193.   else if (ll.ll_time != 0) {
  194.     /* if last login is earlier than some current login */
  195.     for (; !doit && w != NULL; w = w->next)
  196.       if (w->info == LOGGEDIN && w->loginat < ll.ll_time)
  197.     doit = 1;
  198.     /*
  199.      * and if it's not any of the current logins
  200.      * can't use time comparison because there may be a small
  201.      * discrepency since login calls time() twice
  202.      */
  203.     for (w = pn->whead; doit && w != NULL; w = w->next)
  204.       if (w->info == LOGGEDIN &&
  205.       strncmp(w->tty, ll.ll_line, UT_LINESIZE) == 0)
  206.     doit = 0;
  207.   }
  208.   if (doit) {
  209.     w = walloc(pn);
  210.     w->info = LASTLOG;
  211.     bcopy(ll.ll_line, w->tty, UT_LINESIZE);
  212.     w->tty[UT_LINESIZE] = 0;
  213.     bcopy(ll.ll_host, w->host, UT_HOSTSIZE);
  214.     w->host[UT_HOSTSIZE] = 0;
  215.     w->loginat = ll.ll_time;
  216.   }
  217. }
  218.  
  219. enter_where(ut, pn)
  220.      struct utmp *ut;
  221.      PERSON *pn;
  222. {
  223.   register WHERE *w = walloc(pn);
  224.  
  225.   w->info = LOGGEDIN;
  226.   bcopy(ut->ut_line, w->tty, UT_LINESIZE);
  227.   w->tty[UT_LINESIZE] = 0;
  228.   bcopy(ut->ut_host, w->host, UT_HOSTSIZE);
  229.   w->host[UT_HOSTSIZE] = 0;
  230.   w->loginat = (time_t)ut->ut_time;
  231.   find_idle_and_ttywrite(w);
  232. }
  233. #endif
  234.  
  235. PERSON *
  236. enter_person(pw)
  237.      register struct passwd *pw;
  238. {
  239.   register PERSON *pn, **pp;
  240.  
  241.   for (pp = htab + hash(pw->pw_name);
  242.        *pp != NULL && strcmp((*pp)->name, pw->pw_name) != 0;
  243.        pp = &(*pp)->hlink)
  244.     ;
  245.   if ((pn = *pp) == NULL) {
  246.     pn = palloc();
  247.     entries++;
  248.     if (phead == NULL)
  249.       phead = ptail = pn;
  250.     else {
  251.       ptail->next = pn;
  252.       ptail = pn;
  253.     }
  254.     pn->next = NULL;
  255.     pn->hlink = NULL;
  256.     *pp = pn;
  257.     userinfo(pn, pw);
  258.     pn->whead = NULL;
  259.   }
  260.   return(pn);
  261. }
  262.  
  263. PERSON *
  264. find_person(name)
  265.      char *name;
  266. {
  267.   register PERSON *pn;
  268.  
  269.   /* name may be only UT_NAMESIZE long and not terminated */
  270.   for (pn = htab[hash(name)];
  271.        pn != NULL && strncmp(pn->name, name, UT_NAMESIZE) != 0;
  272.        pn = pn->hlink)
  273.     ;
  274.   return(pn);
  275. }
  276.  
  277. int
  278. hash(register char *name)
  279. {
  280.   register int h, i;
  281.  
  282.   h = 0;
  283.   /* name may be only UT_NAMESIZE long and not terminated */
  284.   for (i = UT_NAMESIZE; --i >= 0 && *name;)
  285.     h = ((h << 2 | h >> HBITS - 2) ^ *name++) & HMASK;
  286.   return(h);
  287. }
  288.  
  289. PERSON *
  290. palloc(void)
  291. {
  292.   PERSON *p;
  293.  
  294.   if ((p = (PERSON *)malloc((u_int) sizeof(PERSON))) == NULL) {
  295.     (void)fprintf(stderr, "finger: out of space.\n");
  296.     exit(1);
  297.   }
  298.   return(p);
  299. }
  300.  
  301. WHERE *
  302. walloc(register PERSON *pn)
  303. {
  304.   register WHERE *w;
  305.  
  306.   if ((w = (WHERE *)malloc((u_int) sizeof(WHERE))) == NULL) {
  307.     (void)fprintf(stderr, "finger: out of space.\n");
  308.     exit(1);
  309.   }
  310.   if (pn->whead == NULL)
  311.     pn->whead = pn->wtail = w;
  312.   else {
  313.     pn->wtail->next = w;
  314.     pn->wtail = w;
  315.   }
  316.   w->next = NULL;
  317.   return(w);
  318. }
  319.  
  320. char *
  321. prphone(char *num)
  322. {
  323.   register char *p;
  324.   int len;
  325.   static char pbuf[15];
  326.  
  327.   /* don't touch anything if the user has their own formatting */
  328.   for (p = num; *p; ++p)
  329.     if (!isdigit(*p))
  330.       return(num);
  331.   len = p - num;
  332.   p = pbuf;
  333.   switch(len) {
  334.   case 11:            /* +0-123-456-7890 */
  335.     *p++ = '+';
  336.     *p++ = *num++;
  337.     *p++ = '-';
  338.     /* FALLTHROUGH */
  339.   case 10:            /* 012-345-6789 */
  340.     *p++ = *num++;
  341.     *p++ = *num++;
  342.     *p++ = *num++;
  343.     *p++ = '-';
  344.     /* FALLTHROUGH */
  345.   case 7:            /* 012-3456 */
  346.     *p++ = *num++;
  347.     *p++ = *num++;
  348.     *p++ = *num++;
  349.     break;
  350.   case 5:            /* x0-1234 */
  351.     *p++ = 'x';
  352.     *p++ = *num++;
  353.     break;
  354.   default:
  355.     return(num);
  356.   }
  357.   *p++ = '-';
  358.   *p++ = *num++;
  359.   *p++ = *num++;
  360.   *p++ = *num++;
  361.   *p++ = *num++;
  362.   *p = '\0';
  363.   return(pbuf);
  364. }
  365.  
  366.